package net.xcrane.xmpp.tools.ui;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

import org.jivesoftware.smack.ExceptionCallback;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterListener;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager;
import org.jivesoftware.smackx.ping.PingManager;
import org.jivesoftware.smackx.privacy.PrivacyList;
import org.jivesoftware.smackx.privacy.PrivacyListManager;
import org.jivesoftware.smackx.privacy.packet.PrivacyItem;
import org.jivesoftware.smackx.privacy.packet.PrivacyItem.Type;
import org.jivesoftware.smackx.snyc.packet.APNSToken;
import org.jivesoftware.smackx.snyc.packet.CancelAPNS;
import org.jivesoftware.smackx.snyc.packet.Disturber;
import org.jivesoftware.smackx.snyc.packet.Fin;
import org.jivesoftware.smackx.snyc.packet.OMAmount;
import org.jivesoftware.smackx.snyc.packet.OfflineMessageItems;
import org.jivesoftware.smackx.snyc.packet.OfflineMsgAmount;
import org.jivesoftware.smackx.snyc.packet.OfflineMsgPage;
import org.jivesoftware.smackx.snyc.packet.QuitRoomExtensionElement;
import org.jivesoftware.smackx.snyc.packet.RedEnvelopeElment;
import org.jivesoftware.smackx.xdata.Form;
import org.jivesoftware.smackx.xdata.FormField;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;

public class ConsultantFrame {

	private JFrame frmXmppTools;
	private JTextField txtName;
	private JTextField txtPwd;
	private JTextField txtHost;
	private JTextField txtPort;

	private JTextArea txtMsg = null;
	private JTextArea txtChat = null;
	
	private XMPPTCPConnection xmppCnn = null;
	
	private JTextField txtTo;
	private JTextField txtStatus;
	
	private JScrollPane spMsg = null;
	
	private JTextField txtDomain;	
	private JTextField txtGroup;
	private JTextField txtResource;
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ConsultantFrame window = new ConsultantFrame();
					window.frmXmppTools.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public ConsultantFrame() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {		
		frmXmppTools = new JFrame();
		frmXmppTools.setTitle("XMPP Tools");
		frmXmppTools.setBounds(100, 100, 953, 624);
		frmXmppTools.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmXmppTools.getContentPane().setLayout(null);
		
		JLabel lblName = new JLabel("Name:");
		lblName.setBounds(40, 38, 86, 30);
		frmXmppTools.getContentPane().add(lblName);
		
		txtName = new JTextField();
		txtName.setText("13140167038");
		txtName.setBounds(140, 38, 155, 30);
		frmXmppTools.getContentPane().add(txtName);
		txtName.setColumns(10);
		
		JLabel labelPwd = new JLabel("Password:");
		labelPwd.setBounds(364, 38, 86, 30);
		frmXmppTools.getContentPane().add(labelPwd);
		
		txtPwd = new JTextField();
		txtPwd.setText("111111");
		txtPwd.setColumns(10);
		txtPwd.setBounds(464, 38, 155, 30);
		frmXmppTools.getContentPane().add(txtPwd);
		
		JLabel lblHost = new JLabel("Host:");
		lblHost.setBounds(40, 73, 86, 30);
		frmXmppTools.getContentPane().add(lblHost);
		
		txtHost = new JTextField();
		txtHost.setText("122.114.213.79");
		txtHost.setColumns(10);
		txtHost.setBounds(140, 74, 155, 30);
		frmXmppTools.getContentPane().add(txtHost);
		
		JLabel lblPort = new JLabel("Port:");
		lblPort.setBounds(364, 73, 86, 30);
		frmXmppTools.getContentPane().add(lblPort);
		
		txtPort = new JTextField();
		txtPort.setText("5222");
		txtPort.setColumns(10);
		txtPort.setBounds(464, 73, 155, 30);
		frmXmppTools.getContentPane().add(txtPort);
		
		JLabel lblChat = new JLabel("Chat:");
		lblChat.setBounds(40, 245, 72, 18);
		frmXmppTools.getContentPane().add(lblChat);
		
		JScrollPane spChat = new JScrollPane();
		spChat.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		spChat.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		spChat.setBounds(140, 242, 577, 88);
		frmXmppTools.getContentPane().add(spChat);
		
		txtChat = new JTextArea();
		txtChat.setLineWrap(true);
		spChat.setViewportView(txtChat);
		
		JLabel lblMsg = new JLabel("Message:");
		lblMsg.setBounds(40, 333, 72, 18);
		frmXmppTools.getContentPane().add(lblMsg);
		
		spMsg = new JScrollPane();
		spMsg.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		spMsg.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		spMsg.setBounds(140, 343, 577, 221);
		frmXmppTools.getContentPane().add(spMsg);
		
		txtMsg = new JTextArea();
		txtMsg.setLineWrap(true);
		spMsg.setViewportView(txtMsg);
		
		JButton btnLogon = new JButton("Logon");
		btnLogon.addActionListener(new LogonAction());
		btnLogon.setBounds(789, 14, 134, 27);
		frmXmppTools.getContentPane().add(btnLogon);
		
		JButton btnLogout = new JButton("Logout");
		btnLogout.addActionListener(new LogoutAction(frmXmppTools));
		btnLogout.setBounds(789, 41, 134, 27);
		frmXmppTools.getContentPane().add(btnLogout);
		
		JButton btnSendMsg = new JButton("Send Message");
		btnSendMsg.addActionListener(new SendAction());
		btnSendMsg.setBounds(789, 92, 143, 30);
		frmXmppTools.getContentPane().add(btnSendMsg);
		
		JLabel lblTo = new JLabel("To:");
		lblTo.setBounds(40, 112, 86, 30);
		frmXmppTools.getContentPane().add(lblTo);
		
		txtTo = new JTextField();
		txtTo.setText("15825825858");
		txtTo.setColumns(10);
		txtTo.setBounds(140, 112, 155, 30);
		frmXmppTools.getContentPane().add(txtTo);
		
		JLabel lblStatus = new JLabel("Status");
		lblStatus.setBounds(364, 108, 86, 30);
		frmXmppTools.getContentPane().add(lblStatus);
		
		txtStatus = new JTextField();
		txtStatus.setText("leave");
		txtStatus.setColumns(10);
		txtStatus.setBounds(464, 108, 155, 30);
		frmXmppTools.getContentPane().add(txtStatus);
		
		spMsg.setAutoscrolls(true);
		
		JButton btnClose = new JButton("Close");
		btnClose.addActionListener(new CloseAction());
		btnClose.setBounds(789, 65, 143, 27);
		frmXmppTools.getContentPane().add(btnClose);
		
		JLabel lblDomain = new JLabel("Domain:");
		lblDomain.setBounds(40, 150, 86, 30);
		frmXmppTools.getContentPane().add(lblDomain);
		
		txtDomain = new JTextField();
		txtDomain.setText("sx");
		txtDomain.setColumns(10);
		txtDomain.setBounds(140, 150, 155, 30);
		frmXmppTools.getContentPane().add(txtDomain);
		
		JButton btnClear = new JButton("Clear");
		btnClear.addActionListener(new ClearAction());
		btnClear.setBounds(789, 291, 143, 27);
		frmXmppTools.getContentPane().add(btnClear);
		
		JButton btnFin = new JButton("Fin");
		btnFin.addActionListener(new FinAction());
		btnFin.setBounds(789, 213, 134, 27);
		frmXmppTools.getContentPane().add(btnFin);
		
		JLabel lblGroup = new JLabel("Group:");
		lblGroup.setBounds(364, 147, 86, 30);
		frmXmppTools.getContentPane().add(lblGroup);
		
		txtGroup = new JTextField();
		txtGroup.setText("room1");
		txtGroup.setColumns(10);
		txtGroup.setBounds(464, 147, 155, 30);
		frmXmppTools.getContentPane().add(txtGroup);
		
		JButton btnSendGroupchat = new JButton("Send Group Msg");
		btnSendGroupchat.addActionListener(new SendGroupAction());
		btnSendGroupchat.setBounds(789, 330, 143, 27);
		frmXmppTools.getContentPane().add(btnSendGroupchat);
		
		JButton btnCreateRoom = new JButton("Create Room");
		btnCreateRoom.addActionListener(new CreateRoomAction());
		btnCreateRoom.setBounds(789, 379, 143, 27);
		frmXmppTools.getContentPane().add(btnCreateRoom);
		
		JButton btnChangeNick = new JButton("Change Nick");
		btnChangeNick.addActionListener(new ChangeNickAction());
		btnChangeNick.setBounds(789, 404, 143, 27);
		frmXmppTools.getContentPane().add(btnChangeNick);
		
		JButton btnPresenceRoom = new JButton("Presence Room");
		btnPresenceRoom.addActionListener(new PresenceRoomAction());
		btnPresenceRoom.setBounds(789, 353, 143, 27);
		frmXmppTools.getContentPane().add(btnPresenceRoom);
		
		JButton btnOMAmount = new JButton("OM Amount");
		btnOMAmount.addActionListener(new OmAmountAction());
		btnOMAmount.setBounds(789, 241, 134, 27);
		frmXmppTools.getContentPane().add(btnOMAmount);
		
		JButton btnOMPage = new JButton("OM Page");
		btnOMPage.addActionListener(new OmPageAction());
		btnOMPage.setBounds(789, 269, 134, 27);
		frmXmppTools.getContentPane().add(btnOMPage);
		
		JButton btnDestoryRoom = new JButton("Destory Room");
		btnDestoryRoom.addActionListener(new DestoryRoomAction());
		btnDestoryRoom.setBounds(789, 454, 143, 27);
		frmXmppTools.getContentPane().add(btnDestoryRoom);
		
		JButton butQuitRoom = new JButton("Quit From Room");
		butQuitRoom.addActionListener(new QuitRoomAction());
		butQuitRoom.setBounds(789, 160, 143, 27);
		frmXmppTools.getContentPane().add(butQuitRoom);
		
		JButton btnGetJoinedRooms = new JButton("Get Joined Rooms");
		btnGetJoinedRooms.addActionListener(new GetJoinedRoomsAction());
		btnGetJoinedRooms.setBounds(789, 428, 143, 27);
		frmXmppTools.getContentPane().add(btnGetJoinedRooms);
		
		JButton btnRedEnvelope = new JButton("Red Envelope");
		btnRedEnvelope.addActionListener(new RedEnvelopeAction());
		btnRedEnvelope.setBounds(789, 185, 143, 27);
		frmXmppTools.getContentPane().add(btnRedEnvelope);
		
		JButton btnAddPrivacy = new JButton("Add Privacy");
		btnAddPrivacy.addActionListener(new AddPrivacyAction());
		btnAddPrivacy.setBounds(634, 40, 143, 30);
		frmXmppTools.getContentPane().add(btnAddPrivacy);
		
		JButton btnDeletePrivacy = new JButton("Delete Privacy");
		btnDeletePrivacy.addActionListener(new DeletePrivacyAction());
		btnDeletePrivacy.setBounds(634, 63, 143, 30);
		frmXmppTools.getContentPane().add(btnDeletePrivacy);
		
		JButton btnGetPrivacy = new JButton("Get Privacy");
		btnGetPrivacy.addActionListener(new GetPrivacyAction());
		btnGetPrivacy.setBounds(634, 105, 143, 30);
		frmXmppTools.getContentPane().add(btnGetPrivacy);
		
		JButton btnGetRoster = new JButton("Get Roster");
		btnGetRoster.addActionListener(new GetRosterAction());
		btnGetRoster.setBounds(634, 129, 143, 30);
		frmXmppTools.getContentPane().add(btnGetRoster);
		
		JButton btnAddRosterItem = new JButton("Add Roster Item");
		btnAddRosterItem.addActionListener(new AddRosterItemAction());
		btnAddRosterItem.setBounds(634, 158, 143, 30);
		frmXmppTools.getContentPane().add(btnAddRosterItem);
		
		JButton btnSendWithResponse = new JButton("Send With RSP");
		btnSendWithResponse.addActionListener(new SendWithResponseAction());
		btnSendWithResponse.setBounds(789, 118, 143, 30);
		frmXmppTools.getContentPane().add(btnSendWithResponse);
		
		JButton btnSetApnstoken = new JButton("Set APNSToken");
		btnSetApnstoken.addActionListener(new SetTokenAction());
		btnSetApnstoken.setBounds(634, 184, 143, 30);
		frmXmppTools.getContentPane().add(btnSetApnstoken);
		
		JLabel lblResource = new JLabel("Resource:");
		lblResource.setBounds(40, 188, 86, 30);
		frmXmppTools.getContentPane().add(lblResource);
		
		txtResource = new JTextField();
		txtResource.setText("XMPP-Tools");
		txtResource.setColumns(10);
		txtResource.setBounds(140, 188, 155, 30);
		frmXmppTools.getContentPane().add(txtResource);
		
		JButton btnCancelApns = new JButton("Cancel APNS");
		btnCancelApns.addActionListener(new CancelAPNSAction());
		btnCancelApns.setBounds(634, 211, 143, 30);
		frmXmppTools.getContentPane().add(btnCancelApns);
		
		JButton btnSetupDisturber = new JButton("Setup Disturber");
		btnSetupDisturber.addActionListener(new SetupDisturberAction());
		btnSetupDisturber.setBounds(789, 480, 143, 27);
		frmXmppTools.getContentPane().add(btnSetupDisturber);
		
		JButton btnCancelDisturber = new JButton("Cancel Disturber");
		btnCancelDisturber.addActionListener(new CancelDisturberAction());
		btnCancelDisturber.setBounds(789, 504, 143, 27);
		frmXmppTools.getContentPane().add(btnCancelDisturber);
		
		JButton btnGetDisturberList = new JButton("Get Disturber List");
		btnGetDisturberList.addActionListener(new GetDisturberListAction());
		btnGetDisturberList.setBounds(789, 526, 143, 27);
		frmXmppTools.getContentPane().add(btnGetDisturberList);
	}
	
	
	private void log(String str){
		
		SwingUtilities.invokeLater(new LogUpdateRunner(str));

	}
	
	class LogUpdateRunner implements Runnable{

		private String log = null;
		
		LogUpdateRunner(String log){
			this.log = log;
		}
		
		public void run() {
			txtMsg.append(new Date() + " - " + log + "\r\n");
			txtMsg.append("\r\n");	
			
			JScrollBar vertical = spMsg.getVerticalScrollBar();
			vertical.setValue( vertical.getMaximum() );	
		}		
	}
	
	class LogonAction implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			PingManager.setDefaultPingInterval(60);
			
			// Create a connection to the jabber.org server on a specific port.
			XMPPTCPConnectionConfiguration config = null;
			
			try {
				config = XMPPTCPConnectionConfiguration.builder()
						.setDebuggerEnabled(true)
						.setXmppDomain(txtDomain.getText())
						.setHostAddress(InetAddress.getByName(txtHost.getText()))
						.setPort(Integer.valueOf(txtPort.getText()).intValue())
						.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.disabled)
//						.setResource("XMPP-Tools")
						.setResource(txtResource.getText())
//						.setCompressionEnabled(true)
//						.setSocketFactory(new DummySSLSocketFactory())
						.build();
				
				xmppCnn = new XMPPTCPConnection(config);
				xmppCnn.setUseStreamManagement(false);
				xmppCnn.addAsyncStanzaListener(new IncomeingPacketListener(), null);
				xmppCnn.addPacketSendingListener(new OutcomingPacketInterceptor(), null);
				
				xmppCnn.connect();
				
				xmppCnn.login(txtName.getText(), txtPwd.getText());
			} catch (Exception e1) {
				log(e1.getMessage());			
			}
			
			
//			Presence presence = new Presence(Presence.Type.available);
//			presence.setStatus("I am chatting");
			// Send the packet (assume we have a XMPPConnection instance called "con").
			try {
//				xmppCnn.sendStanza(presence);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class LogoutAction implements ActionListener {
		JFrame frame  = null;
		
		public LogoutAction(JFrame frame){
			this.frame = frame;
		}		
		
		public void actionPerformed(ActionEvent e) {
			Presence presence = new Presence(Presence.Type.unavailable);
			presence.setStatus("offline");
			
			// Send the packet (assume we have a XMPPConnection instance called "xmppCnn").			
			try {
				xmppCnn.disconnect(presence);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
			
		}
	}
	
	
	class CloseAction implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			frmXmppTools.dispose();
		}
	}
	
	
	class SendAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();
			newMessage.setType(Message.Type.chat);
			newMessage.setBody(txtChat.getText());
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtTo.getText() + "@" + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
				
				xmppCnn.sendStanza(newMessage);				
				
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class SendWithResponseAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();
			newMessage.setType(Message.Type.chat);
			newMessage.setBody(txtChat.getText());
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtTo.getText() + "@" + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
								
				xmppCnn.sendStanzaWithResponseCallback(newMessage, new MessageIDFilter(newMessage), 
						new MessageResponseListener(newMessage), new MessageExceptionCallback(), 5 * 1000);
								
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	 class MessageIDFilter implements StanzaFilter {
		 private Message message;
		 
		 MessageIDFilter(Message message){
			 this.message = message;
		 }
		 
	     public boolean accept(Stanza stanza) {
	         return message.getStanzaId().equals(stanza.getStanzaId());
	     }
	 };
	 
	 
	class MessageResponseListener implements  StanzaListener{
		 private Message message;
		 
		 MessageResponseListener(Message message){
			 this.message = message;
		 }
		
		public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
        	if(packet instanceof Message){
        		Message msg = (Message)packet;        		
        		msg.getError();
                log("the message : [" + message.toXML() + "] ,\n the responsed message : [" + msg.toXML() + "]");
        	}
		}	
	}
	 
	class MessageExceptionCallback implements ExceptionCallback{

		public void processException(Exception exception) {
			log("waitting message response ang get the exeption : " + exception);
		}
		
	}
	
	class AddPrivacyAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			
			// Set the name of the list_
			String listName = "public";

			// Create the list of PrivacyItem that will allow or deny some privacy aspect_
			String user = txtTo.getText() + "@" + txtDomain.getText();
//			String groupName = "enemies";
			ArrayList<PrivacyItem> privacyItems = new ArrayList<PrivacyItem>();

			PrivacyItem item = new PrivacyItem(Type.jid, user, false, 1);
			item.isFilterEverything();
			
			privacyItems.add(item);

//			user = "tsung2@sun";
//			item = new PrivacyItem(Type.jid, user, false, 1);
//			item.isFilterEverything();
//			privacyItems.add(item);
			
//			user = "tsung3@sun";
//			item = new PrivacyItem(Type.jid, user, false, 1);
//			item.isFilterEverything();
//			privacyItems.add(item);
			
//			item = new PrivacyItem(PrivacyItem.Type.subscription, PrivacyItem.SUBSCRIPTION_BOTH, true, 2);
//			privacyItems.add(item);

//			item = new PrivacyItem(PrivacyItem.Type.group, groupName, false, 3);
//			item.setFilterMessage(true);
//			privacyItems.add(item);

			// Get the privacy manager for the current connection._
			PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(xmppCnn);
			// Create the new list._
			try {
				privacyManager.createPrivacyList(listName, privacyItems);
				privacyManager.setDefaultListName(listName);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class GetPrivacyAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {			
			
			PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(xmppCnn);
			// Retrieve server privacy lists_
			 PrivacyList lists = null;
			 
			try {
				lists = privacyManager.getDefaultList();			
				log(lists.toString());
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class DeletePrivacyAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			PrivacyListManager privacyManager = PrivacyListManager.getInstanceFor(xmppCnn);
			// Retrieve server privacy lists_			 
			try {
				privacyManager.deletePrivacyList("public");			
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class GetRosterAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {			
			
			Roster roster = Roster.getInstanceFor(xmppCnn);
			Collection<RosterEntry> entries = roster.getEntries();
			for (RosterEntry entry : entries) {
				log(entry.toString());
			}
			 
			roster.addRosterListener(new RosterListener() {
				public void presenceChanged(Presence presence) {
					log("Presence changed: " + presence.getFrom() + " - " + presence);
				}
				
				public void entriesAdded(Collection<Jid> addresses) {
					for (Jid entry : addresses) {
						log(entry.toString());
					}					
				}
				public void entriesUpdated(Collection<Jid> addresses) {
					for (Jid entry : addresses) {
						log(entry.toString());
					}	
				}
				public void entriesDeleted(Collection<Jid> addresses) {
					for (Jid entry : addresses) {
						log(entry.toString());
					}
				}
			});
		}
	}
	
	
	class AddRosterItemAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Roster roster = Roster.getInstanceFor(xmppCnn);

			try {
				roster.createEntry(JidCreate.entityBareFrom(txtTo.getText().trim() + "@" + txtDomain.getText()),
						txtTo.getText().trim(), null);
			} catch (Exception e1) {
				log(e1.getMessage());
			}
		}
	}
	
	class RedEnvelopeAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();
			newMessage.setType(Message.Type.chat);

			RedEnvelopeElment redEnvelope = new RedEnvelopeElment();
			redEnvelope.setId("11");
			redEnvelope.setFrom(txtName.getText());
			redEnvelope.setTo(txtTo.getText());
			redEnvelope.setAmount("50");
			newMessage.addExtension(redEnvelope);
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtTo.getText() + "@" + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
				
				xmppCnn.sendStanza(newMessage);	
				
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class QuitRoomAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();
			newMessage.setType(Message.Type.groupchat);
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtGroup.getText() + "@conference." + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));
				newMessage.addExtension(new QuitRoomExtensionElement());
				
				xmppCnn.sendStanza(newMessage);	
				
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class SendGroupAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Message newMessage = new Message();			
			newMessage.setType(Message.Type.groupchat);			
			newMessage.setBody(txtChat.getText());
			
			try {
				newMessage.setTo(JidCreate.entityBareFrom(txtGroup.getText() + "@conference." + txtDomain.getText()));
				newMessage.setFrom(JidCreate.entityBareFrom(txtName.getText() + "@" + txtDomain.getText()));

				xmppCnn.sendStanza(newMessage);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class CreateRoomAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {		
			// Get the MultiUserChatManager
			MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(xmppCnn);

			try {
				// Create the XMPP address (JID) of the MUC.
				EntityBareJid mucJid = (EntityBareJid)JidCreate.bareFrom(txtGroup.getText() + "@conference." + txtDomain.getText());
				// Create the nickname.
				Resourcepart nickname = Resourcepart.from(txtName.getText());
				
				// Create a MultiUserChat using an XMPPConnection for a room
				MultiUserChat muc = manager.getMultiUserChat(mucJid);

				// Prepare a list of owners of the new room
//				Set<Jid> owners = JidUtil.jidSetFrom(new String[] { "me@example.org", "juliet@example.org" });

				// Create the room
/*				muc.create(nickname)
					.getConfigFormManager()
					.submitConfigurationForm();*/
				
				muc.create(nickname);

		        // Set the answer form
		        Form configForm = muc.getConfigurationForm();
		        Form answerForm = configForm.createAnswerForm();
		        
		        // Add the default answers to the form to submit
		        for (FormField field : configForm.getFields()) {
		            if (field.getType() == FormField.Type.hidden
		                            || StringUtils.isNullOrEmpty(field.getVariable())) {
		                continue;
		            }
		            answerForm.setDefaultAnswer(field.getVariable());
		        }
				
				// Sets the new owner of the room
				List<String> owners = new ArrayList<String>();
				owners.add(txtName.getText() + "@" + txtDomain.getText());
		        answerForm.setAnswer("muc#roomconfig_roomowners", owners);
		        answerForm.setAnswer("muc#roomconfig_persistentroom", true);
		        answerForm.setAnswer("muc#roomconfig_membersonly", true);
		        answerForm.setAnswer("muc#roomconfig_allowinvites", true);
		        answerForm.setAnswer("muc#roomconfig_changesubject", true);
				
				// Send the completed form (with default values) to the server to
				// configure the room
				muc.sendConfigurationForm(answerForm);				
			} catch (Exception e1) {
					e1.printStackTrace();
					log(e1.getMessage());
			}
		}
	}
	
	class PresenceRoomAction implements ActionListener {
	
		public void actionPerformed(ActionEvent e) {
			// Get the MultiUserChatManager
			MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(xmppCnn);

			try {
				// Create the XMPP address (JID) of the MUC.
				EntityBareJid mucJid = (EntityBareJid)JidCreate.bareFrom(txtGroup.getText() + "@conference." + txtDomain.getText());
				
				// Create a MultiUserChat using an XMPPConnection for a room
				MultiUserChat muc = manager.getMultiUserChat(mucJid);
				
				Resourcepart nickname = Resourcepart.from(txtName.getText());
				muc.join(nickname);
			}catch(Exception e1){
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	

	class ChangeNickAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {			
			// Get the MultiUserChatManager
			MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(xmppCnn);

			try {
				// Create the XMPP address (JID) of the MUC.
				EntityBareJid mucJid = (EntityBareJid)JidCreate.bareFrom(txtGroup.getText() + "@conference." + txtDomain.getText());
				
				// Create a MultiUserChat using an XMPPConnection for a room
				MultiUserChat muc = manager.getMultiUserChat(mucJid);

				// Create the nickname.
				Resourcepart nickname = Resourcepart.from(txtName.getText());
				muc.join(nickname);
				muc.changeNickname(nickname);;
			}catch(Exception e1){
				e1.printStackTrace();
				log(e1.getMessage());
			}			
		}
	}
	
	class GetJoinedRoomsAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {			
			// Get the MultiUserChatManager
			MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(xmppCnn);

			try {
				// Create the XMPP address (JID) of the MUC.
				EntityBareJid mucJid = (EntityBareJid)JidCreate.bareFrom(txtGroup.getText() + "@conference." + txtDomain.getText());
				
				// Create a MultiUserChat using an XMPPConnection for a room
				MultiUserChat muc = manager.getMultiUserChat(mucJid);
				
				// Get the rooms where the user has joined
				Set<EntityBareJid> joinedRooms = manager.getJoinedRooms();
				
				log(joinedRooms.toString());
			}catch(Exception e1){
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class DestoryRoomAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {			
			// Get the MultiUserChatManager
			MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(xmppCnn);

			try {
				// Create the XMPP address (JID) of the MUC.
				EntityBareJid mucJid = (EntityBareJid)JidCreate.bareFrom(txtGroup.getText() + "@conference." + txtDomain.getText());
				
				// Create a MultiUserChat using an XMPPConnection for a room
				MultiUserChat muc = manager.getMultiUserChat(mucJid);
				
				muc.destroy("", mucJid);
			}catch(Exception e1){
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class FinAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			Fin packet = new Fin();
			packet.setVersion(Long.parseLong(txtChat.getText()));		
			log("FIN = " + packet.toXML());

			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class SetTokenAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			APNSToken packet = new APNSToken();
			packet.setId(txtChat.getText());
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}

	class CancelAPNSAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			CancelAPNS packet = new CancelAPNS();
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class ClearAction implements ActionListener {	
		public void actionPerformed(ActionEvent e) {
			txtMsg.setText("");
		}
	}
	
	
	class IncomeingPacketListener implements StanzaListener{		
		public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
        	log("RCVD: " + packet.toXML());
        	
        	if(packet instanceof Message){
        		Message msg = (Message)packet;
        		ExtensionElement elmt = msg.getExtension("receipt", "fc:msg:srv");
        		if(elmt != null){
                	log("ExtensionElement: " + elmt.toXML());
        		}
        		
        		if(msg.getType().equals(Message.Type.error)){
            		XMPPError err = msg.getError();
            		if(err != null){
            			log("ERROR CODE = " + err.getCode());
            		}       			
        		}
        		
        	}else if(packet instanceof IQ){
        		if(packet instanceof OMAmount){ 			
        			OMAmount omAmount = (OMAmount)packet;    			
        			log("OMAmount: " + packet.toXML() + "， amount = " + omAmount.getAmount());	
        		}else if(packet instanceof OfflineMessageItems){
        			OfflineMessageItems items = (OfflineMessageItems)packet;
        			log("items count = " + items.getCount());	
        			for(Message msg : items.getOfflineMessageItems()){
            			log(msg.toXML().toString());	
        			}
        		}
        	}
		}
	}
	
	
	class OutcomingPacketInterceptor implements StanzaListener{
		public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
        	log("SEND: " + packet.toXML().toString());			
		}	
	}
	
	
	class OmAmountAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			OfflineMsgAmount packet = new OfflineMsgAmount();
			
			try {
				xmppCnn.sendStanza(packet);			
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class OmPageAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			OfflineMsgPage packet = new OfflineMsgPage();
			packet.setLimit("10");
			packet.setVersion(txtChat.getText());
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class SetupDisturberAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Disturber packet = new Disturber();
			packet.setActoin(Disturber.ATTR_ACTION_SETUP);
		
			//for user
//			packet.setItemType(Disturber.ATTR_TYPE_USER);
//			packet.setJid(txtTo.getText() + "." + txtDomain.getText());

			//for room
			packet.setItemType(Disturber.ATTR_TYPE_ROOM);
			packet.setJid(txtGroup.getText() + "@conference." + txtDomain.getText());
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	
	class CancelDisturberAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Disturber packet = new Disturber();
//			packet.setItemType(Disturber.ATTR_TYPE_USER);
			packet.setActoin(Disturber.ATTR_ACTION_CANCEL);
			packet.setJid(txtTo.getText() + "@" + txtDomain.getText());

			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
	
	class GetDisturberListAction implements ActionListener {
		
		public void actionPerformed(ActionEvent e) {
			Disturber packet = new Disturber();
			packet.setType(IQ.Type.get);
			
			try {
				xmppCnn.sendStanza(packet);
			} catch (Exception e1) {
				e1.printStackTrace();
				log(e1.getMessage());
			}
		}
	}
}
